﻿package Network
{	
	import com.junkbyte.console.Cc;
	
	import Core.Game;

	import flash.net.Socket;	
	import flash.net.registerClassAlias;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.EventDispatcher;
	import flash.system.Security;
	import flash.utils.ByteArray;

	public class TCPClient extends EventDispatcher 
	{
		private static const REG:* = registerClassAlias("FlashServer.DataMessage", DataMessage);
		
		private var FGame:Game;
		private var FSocket:Socket;		
		private var FRecivingBuffer:ByteArray;
		
		public function TCPClient(AGame:Game):void
		{
			FGame = AGame;
			FSocket = new Socket();
			FSocket.addEventListener(Event.CONNECT, OnSocketConnected);
			FSocket.addEventListener(Event.CLOSE, OnSocketClose);
			FSocket.addEventListener(IOErrorEvent.IO_ERROR, OnSocketIOError);
			FSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, OnScoketSecurityError);
			FSocket.addEventListener(ProgressEvent.SOCKET_DATA, OnSocketData);
		}
		
		public function Connect():void
		{			
			Cc.log('Loading multiplayer policy file...');			
			Security.loadPolicyFile(FGame.Settings.PolicyServer);
			
			Cc.log('Connecting to multiplayer server...');
			try
			{
				FSocket.connect(FGame.Settings.Host, FGame.Settings.Port);
			}
			catch(e:Error)
			{
				Cc.error('Socket connection error: ' + e.message);
			}
		}
		
		public function Send(AMessage:DataMessage):void
		{		
			try 
			{					
				FSocket.writeObject(AMessage);
				FSocket.flush();
			}
			catch(e:Error)
			{
				Cc.error('Message sendig error: ' + e.message);
			}
		}
		
		public function get IsConnected():Boolean
		{
			return FSocket.connected;
		}
		
		private function OnSocketConnected(e:Event):void
		{			
			dispatchEvent(new Event(Event.CONNECT));
		}
		
		private function OnSocketClose(e:Event):void
		{
			dispatchEvent(new Event(Event.CLOSE));
		}
		
		private function OnSocketIOError(e:IOErrorEvent):void
		{
			dispatchEvent(e);
			Cc.error('TCP: ' + e.text);
		}
		
		private function OnScoketSecurityError(e:SecurityErrorEvent):void
		{
			dispatchEvent(e);
			Cc.error('TCP: ' + e.text);
		}
		
		private function OnSocketData(e:ProgressEvent):void
		{
			FRecivingBuffer = new ByteArray();
			FSocket.readBytes(FRecivingBuffer, 0, FSocket.bytesAvailable);
			
			var vMessage:DataMessage = FRecivingBuffer.readObject() as DataMessage;
			if (vMessage)
			{				
				var vEvent:TCPMessageEvent = new TCPMessageEvent(vMessage);			
				dispatchEvent(vEvent);
			}
		}
	}	
}
